package com.mvp.lt.airlineview.utils;

import com.amap.api.maps.AMap;
import com.amap.api.maps.model.Circle;
import com.amap.api.maps.model.CircleOptions;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.Polygon;
import com.amap.api.maps.model.PolygonOptions;
import com.amap.api.maps.model.Polyline;
import com.amap.api.maps.model.PolylineOptions;
import com.amap.api.services.core.LatLonPoint;
import com.mvp.lt.airlineview.map.MapCalculationLogLatDistance;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by MapShadowUtils.
 * User: Administrator
 * Name: AirLineView
 * functiona: 影子轨迹
 * Date: 2019/10/16 0016
 * Time: 下午 17:24
 */
public class MapShadowManager {
    private AMap m3DAMap;
    private Polyline mPolyline2 = null;

    private List<Marker> mMarkerList = new ArrayList<>();
    private List<LatLng> latLngs = new ArrayList<>();
    private List<LatLng> mLatLngs = new ArrayList<>();
    public Polygon mRangePolygon;

    public void clrarMap() {


        if (latLngs != null) {
            latLngs.clear();
        }
        if (mLatLngs != null) {
            mLatLngs.clear();
        }

        if (mPolyline2 != null) {
            mPolyline2.remove();
        }
        if (mRangePolygon != null) {
            mRangePolygon.remove();
        }
        if (mPolyline2 != null) {
            mPolyline2.remove();
        }
        for (int i = 0; i < mMarkerList.size(); i++) {
            mMarkerList.get(i).destroy();
        }
        if (mMarkerList != null) {
            mMarkerList.clear();
        }

    }

    private int fov;


    public MapShadowManager(AMap m3DAMap, int fov) {
        this.m3DAMap = m3DAMap;
        this.fov = fov;
    }


    public void addLnglatMapClick(LatLng latLng, int height) {
        mLatLngs.add(latLng);

        if (mPolyline2 != null) {
            mPolyline2.remove();
        }

        double distance = (height / 1000f) * Math.tan(Math.toRadians(fov / 2));
        mPolyline2 = drawPolyLineOptions(m3DAMap, mLatLngs, 5, 0xFF000000);
        if (mLatLngs.size() > 2) {
            LatLng latLng1 = mLatLngs.get(mLatLngs.size() - 2);
            LatLng latLng2 = mLatLngs.get(mLatLngs.size() - 1);
            //两个点算出 获取角度
            double angle = getAngle(latLng1.latitude, latLng1.longitude, latLng2.latitude, latLng2.longitude);
            LogUtil.e("角度", angle + "----------------------------------------------------------");

            LatLonPoint latLonPointleft2 = AMapUtil.convertDistanceToLogLat(latLng2.longitude, latLng2.latitude, distance, angle + 90);

            LatLonPoint latLonPointright2 = AMapUtil.convertDistanceToLogLat(latLng2.longitude, latLng2.latitude, distance, angle - 90);

            latLngs.add(0, new LatLng(latLonPointright2.getLatitude(), latLonPointright2.getLongitude()));
            latLngs.add(new LatLng(latLonPointleft2.getLatitude(), latLonPointleft2.getLongitude()));


            addPolylinesEcircle(latLng2, height);
        } else if (mLatLngs.size() == 2) {
            LatLng latLng1 = mLatLngs.get(mLatLngs.size() - 2);
            LatLng latLng2 = mLatLngs.get(mLatLngs.size() - 1);
            //获取角度
            double angle = getAngle(latLng1.latitude, latLng1.longitude, latLng2.latitude, latLng2.longitude);
            //距离
            LatLonPoint latLonPointleft1 = AMapUtil.convertDistanceToLogLat(latLng1.longitude, latLng1.latitude, distance, angle + 90);

            LatLonPoint latLonPointright1 = AMapUtil.convertDistanceToLogLat(latLng1.longitude, latLng1.latitude, distance, angle - 90);

            LatLonPoint latLonPointleft2 = AMapUtil.convertDistanceToLogLat(latLng2.longitude, latLng2.latitude, distance, angle + 90);

            LatLonPoint latLonPointright2 = AMapUtil.convertDistanceToLogLat(latLng2.longitude, latLng2.latitude, distance, angle - 90);
            latLngs.add(0, new LatLng(latLonPointright1.getLatitude(), latLonPointright1.getLongitude()));
            latLngs.add(new LatLng(latLonPointleft1.getLatitude(), latLonPointleft1.getLongitude()));

            latLngs.add(0, new LatLng(latLonPointright2.getLatitude(), latLonPointright2.getLongitude()));
            latLngs.add(new LatLng(latLonPointleft2.getLatitude(), latLonPointleft2.getLongitude()));

            addPolylinesScircle(latLng1, height);
            addPolylinesEcircle(latLng2, height);
        } else {

            addPolylinesScircle(latLng, height);
        }
        if (mRangePolygon != null) {
            mRangePolygon.remove();
        }
        mRangePolygon = drawPolygonOptions(latLngs);

    }


    /**
     * @param latLng
     * @param height
     */
    public void addLnglatLineWaypointMap(LatLng latLng, int height) {
        mLatLngs.add(latLng);
        if (mPolyline2 != null) {
            mPolyline2.remove();
        }
        // km
        double distance = 0.1;
        mMarkerList.add(getMarker(latLng));
        mPolyline2 = drawPolyLineOptions(m3DAMap, mLatLngs, 5, 0xFF000000);
        if (mLatLngs.size() > 2) {
            LatLng latLng0 = mLatLngs.get(mLatLngs.size() - 3);
            LatLng latLng1 = mLatLngs.get(mLatLngs.size() - 2);
            LatLng latLng2 = mLatLngs.get(mLatLngs.size() - 1);
            //计算带状航线内角
            int minDegree = (int) MapCalculationLogLatDistance.getTriangleAngle(latLng0.latitude, latLng0.longitude, latLng1.latitude, latLng1.longitude, latLng2.latitude, latLng2.longitude);
            int maxDegree = 90;
            LogUtil.e("角度 minDegree", minDegree + "-----------------------------------------------------");
            if (minDegree == 180 || minDegree == 0) {
                minDegree = 90;
                maxDegree = -90;
            } else {
                minDegree = minDegree / 2;
                maxDegree = 180 - minDegree;
            }
            //两个点算出 获取角度
            int startAngle = (int) getAngle(latLng0.latitude, latLng0.longitude, latLng1.latitude, latLng1.longitude);
            double linelength;
            if (minDegree < 20) {
                linelength = distance;
            } else {
                linelength = MapCalculationLogLatDistance.cacleHypotenuseLong(minDegree, distance);
            }
            //计算带状航线长度

            LogUtil.e("角度", startAngle + "------" + minDegree + "---" + maxDegree);
            int endAngle = (int) getAngle(latLng1.latitude, latLng1.longitude, latLng2.latitude, latLng2.longitude);
            //   178------58---122
            LogUtil.e("角度", endAngle + "------" + minDegree + "---" + maxDegree);
            int l1;//300?
            int r1;//120
            LatLonPoint latLonPointleft2;
            LatLonPoint latLonPointright2;
            if (endAngle - startAngle > 0 && Math.abs(endAngle - startAngle) <= 180) {//左拐

                r1 = startAngle + (180 - minDegree);//300?
                l1 = startAngle - (180 - maxDegree);//120
                LatLonPoint latLonPointleft1 = AMapUtil.convertDistanceToLogLat(latLng1.longitude, latLng1.latitude, linelength, l1);
                LatLonPoint latLonPointright1 = AMapUtil.convertDistanceToLogLat(latLng1.longitude, latLng1.latitude, linelength, r1);

                latLonPointleft2 = AMapUtil.convertDistanceToLogLat(latLng2.longitude, latLng2.latitude, distance, endAngle - 90);
                latLonPointright2 = AMapUtil.convertDistanceToLogLat(latLng2.longitude, latLng2.latitude, distance, endAngle + 90);

                latLngs.set(0, new LatLng(latLonPointleft1.getLatitude(), latLonPointleft1.getLongitude()));
                latLngs.set(latLngs.size() - 1, new LatLng(latLonPointright1.getLatitude(), latLonPointright1.getLongitude()));

            } else if (endAngle - startAngle < 0 && Math.abs(endAngle - startAngle) > 180) {//左拐
                r1 = startAngle + (180 - minDegree);//300?
                l1 = startAngle - (180 - maxDegree);//120
                LatLonPoint latLonPointleft1 = AMapUtil.convertDistanceToLogLat(latLng1.longitude, latLng1.latitude, linelength, l1);
                LatLonPoint latLonPointright1 = AMapUtil.convertDistanceToLogLat(latLng1.longitude, latLng1.latitude, linelength, r1);

                latLonPointleft2 = AMapUtil.convertDistanceToLogLat(latLng2.longitude, latLng2.latitude, distance, endAngle - 90);
                latLonPointright2 = AMapUtil.convertDistanceToLogLat(latLng2.longitude, latLng2.latitude, distance, endAngle + 90);

                latLngs.set(0, new LatLng(latLonPointleft1.getLatitude(), latLonPointleft1.getLongitude()));
                latLngs.set(latLngs.size() - 1, new LatLng(latLonPointright1.getLatitude(), latLonPointright1.getLongitude()));
            } else {  //右拐
                l1 = startAngle + (180 - maxDegree);//300?
                r1 = startAngle - (180 - minDegree);//120
                LatLonPoint latLonPointleft1 = AMapUtil.convertDistanceToLogLat(latLng1.longitude, latLng1.latitude, linelength, l1);
                LatLonPoint latLonPointright1 = AMapUtil.convertDistanceToLogLat(latLng1.longitude, latLng1.latitude, linelength, r1);

                latLonPointleft2 = AMapUtil.convertDistanceToLogLat(latLng2.longitude, latLng2.latitude, distance, endAngle - 90);
                latLonPointright2 = AMapUtil.convertDistanceToLogLat(latLng2.longitude, latLng2.latitude, distance, endAngle + 90);


                latLngs.set(0, new LatLng(latLonPointright1.getLatitude(), latLonPointright1.getLongitude()));
                latLngs.set(latLngs.size() - 1, new LatLng(latLonPointleft1.getLatitude(), latLonPointleft1.getLongitude()));
            }

            latLngs.add(0, new LatLng(latLonPointleft2.getLatitude(), latLonPointleft2.getLongitude()));
            latLngs.add(new LatLng(latLonPointright2.getLatitude(), latLonPointright2.getLongitude()));

//            addPolylinesEcircle(latLng2, height);
        } else if (mLatLngs.size() == 2) {

            LatLng latLng1 = mLatLngs.get(mLatLngs.size() - 2);
            LatLng latLng2 = mLatLngs.get(mLatLngs.size() - 1);
            //获取角度
            double angle = getAngle(latLng1.latitude, latLng1.longitude, latLng2.latitude, latLng2.longitude);
            LogUtil.e("角度", angle + "");
            //距离
            LatLonPoint latLonPointleft1 = AMapUtil.convertDistanceToLogLat(latLng1.longitude, latLng1.latitude, distance, angle + 90);

            LatLonPoint latLonPointright1 = AMapUtil.convertDistanceToLogLat(latLng1.longitude, latLng1.latitude, distance, angle - 90);

            LatLonPoint latLonPointleft2 = AMapUtil.convertDistanceToLogLat(latLng2.longitude, latLng2.latitude, distance, angle + 90);

            LatLonPoint latLonPointright2 = AMapUtil.convertDistanceToLogLat(latLng2.longitude, latLng2.latitude, distance, angle - 90);

            latLngs.add(0, new LatLng(latLonPointright1.getLatitude(), latLonPointright1.getLongitude()));
            latLngs.add(new LatLng(latLonPointleft1.getLatitude(), latLonPointleft1.getLongitude()));

            latLngs.add(0, new LatLng(latLonPointright2.getLatitude(), latLonPointright2.getLongitude()));
            latLngs.add(new LatLng(latLonPointleft2.getLatitude(), latLonPointleft2.getLongitude()));

        }
        if (mRangePolygon != null) {
            mRangePolygon.remove();
        }
        mRangePolygon = drawPolygonOptions(latLngs);

    }

    private Polygon drawPolygonOptions(List<LatLng> linelatLngs) {
        PolygonOptions polygonOptions = new PolygonOptions();
        polygonOptions.addAll(linelatLngs);
        polygonOptions.strokeWidth(0) // 多边形的边框
                .strokeColor(0x33000000) // 边框颜色
                .fillColor(0x33000000);   // 多边形的填充色
        return m3DAMap.addPolygon(polygonOptions);
    }

    Circle startCircle;
    Circle endCircle;

    /**
     * @param centerpoint 中心点坐标
     * @param radius      半径 1公里(km)=1000米(m)
     */
    public void addPolylinesScircle(LatLng centerpoint, int radius) {
        if (startCircle == null) {
            startCircle = m3DAMap.addCircle(new CircleOptions()
                    .strokeColor(0x33000000)
                    .fillColor(0x33000000)
                    .strokeWidth(0));
        }

        startCircle.setRadius(radius - radius * 0.1);

        startCircle.setCenter(centerpoint);
    }

    /**
     * @param centerpoint 中心点坐标
     * @param radius      半径 1公里(km)=1000米(m)
     */
    public void addPolylinesEcircle(LatLng centerpoint, int radius) {
        if (endCircle == null) {
            endCircle = m3DAMap.addCircle(new CircleOptions()
                    .strokeColor(0x33000000)
                    .fillColor(0x33000000)
                    .strokeWidth(0));
        }

        endCircle.setRadius(radius - radius * 0.1);
        endCircle.setCenter(centerpoint);
    }

    private Marker getMarker(LatLng latLng) {
        final MarkerOptions markerOptions = new MarkerOptions().position(latLng).zIndex(2);
        Marker marker = m3DAMap.addMarker(markerOptions);
        marker.setAnchor(0.5f, 1f);
        marker.setDraggable(true);

        return marker;
    }

    public Polyline drawPolyLineOptions(AMap aMap, List<LatLng> linelatLngs,
                                        int w, int color) {
        PolylineOptions polylineOptions = new PolylineOptions();
        polylineOptions.addAll(linelatLngs);
        polylineOptions.width(w) // 多边形的边框
                .color(color); // 边框颜色
        return aMap.addPolyline(polylineOptions);
    }

    //一段线

    public Polyline drawOneLenthPolyline(AMap amap, List<Marker> markerList, int w, int color) {
        List<LatLng> points = new ArrayList<LatLng>();
        PolylineOptions opts = new PolylineOptions();
        try {
            if (markerList == null) {
                return null;
            } else if (markerList.size() > 1) {
                Marker marker0 = markerList.get(markerList.size() - 2);
                Marker marker1 = markerList.get(markerList.size() - 1);
                points.add(marker0.getPosition());
                points.add(marker1.getPosition());
                opts.addAll(points);
                opts.width(w);
                opts.color(color);
                opts.zIndex(1);
                return amap.addPolyline(opts);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }    //一段线

    public Polyline drawOneLenthPolyline(AMap amap, LatLng latLng1, LatLng latLng2) {
        List<LatLng> points = new ArrayList<LatLng>();
        PolylineOptions opts = new PolylineOptions();
        points.add(latLng1);
        points.add(latLng2);
        opts.addAll(points);
        opts.width(10);
        opts.color(0x59000000);
        opts.zIndex(1);
        return amap.addPolyline(opts);
    }

    /**
     * 我的点
     *
     * @param lat_a 纬度1
     * @param lng_a 经度1
     *
     *              <p>
     *              <p>
     *              对着的 目标点/兴趣点
     * @param lat_b 纬度2
     * @param lng_b 经度2
     *              <p>
     *              逆时针
     * @return
     */
    public double getAngle(double lat_a, double lng_a, double lat_b, double lng_b) {
        double angle = computeAzimuth(new LatLng(lat_a, lng_a), new LatLng(lat_b, lng_b));
        if (Double.isNaN(angle)) {
            return 270;
        } else {
            return angle;
        }

    }

    private static double computeAzimuth(LatLng la1, LatLng la2) {
        double lat1 = la1.latitude, lon1 = la1.longitude, lat2 = la2.latitude,
                lon2 = la2.longitude;
        double result = 0.0;

        int ilat1 = (int) (0.50 + lat1 * 360000.0);
        int ilat2 = (int) (0.50 + lat2 * 360000.0);
        int ilon1 = (int) (0.50 + lon1 * 360000.0);
        int ilon2 = (int) (0.50 + lon2 * 360000.0);

        lat1 = Math.toRadians(lat1);
        lon1 = Math.toRadians(lon1);
        lat2 = Math.toRadians(lat2);
        lon2 = Math.toRadians(lon2);

        if ((ilat1 == ilat2) && (ilon1 == ilon2)) {
            return result;
        } else if (ilon1 == ilon2) {
            if (ilat1 > ilat2) {
                result = 180.0;
            }
        } else {
            double c = Math
                    .acos(Math.sin(lat2) * Math.sin(lat1) + Math.cos(lat2)
                            * Math.cos(lat1) * Math.cos((lon2 - lon1)));
            double A = Math.asin(Math.cos(lat2) * Math.sin((lon2 - lon1))
                    / Math.sin(c));
            result = Math.toDegrees(A);
            if ((ilat2 > ilat1) && (ilon2 > ilon1)) {
            } else if ((ilat2 < ilat1) && (ilon2 < ilon1)) {
                result = 180.0 - result;
            } else if ((ilat2 < ilat1) && (ilon2 > ilon1)) {
                result = 180.0 - result;
            } else if ((ilat2 > ilat1) && (ilon2 < ilon1)) {
                result += 360.0;
            }
        }
        return result;
    }


    public void setFov(int fov) {
        this.fov = fov;
    }
}
